package testtiles;

import java.awt.Color;
import java.awt.Graphics2D;
import java.util.ArrayList;

import testtiles.Map.Tile;
import testtiles.object.Messages;
import butines.core.game.Drawing;
import butines.core.math2d.Vector2D;
import butines.game.Messenger;

public class World {

	private int targetFps;
	private Messenger messenger = new Messenger();
	private ArrayList<Unit> units = new ArrayList<Unit>();
	private float frameTime;
	private Map map;
	
	public World(Map map) {
		this.map = map;
	}
	
	public int getTargetFps() {
		return targetFps;
	}

	public void setTargetFps(int targetFps) {
		this.targetFps = targetFps;
	}

	public void draw(Graphics2D g2d) {
		map.draw(g2d);
		debug(map);
		for (Unit unit : units) {
			debug(unit);
		}
		for (Unit unit : units) {
			unit.draw(g2d);
		}
	}

	public void update(float tpf) {
		frameTime += tpf;
		messenger.dispatchMessages(frameTime);
		for (Unit unit : units) {
			unit.update(tpf);
		}
	}

	public Messenger getMessenger() {
		return messenger;
	}

	public Map getMap() {
		return map;
	}
	
	public ArrayList<Unit> getUnits() {
		return units;
	}

	public void addUnit(Unit unit) {
		units.add(unit);
		unit.setWorld(this);
	}

	public Unit createUnit(UnitClass unitClass) {
		Unit unit = new Unit(unitClass);
		addUnit(unit);
		return unit;
	}
	
	public void enforceNonPenetrationContraint(Unit unit) {
		for (Unit other : units) {
			if (unit == other || other == null) {
				return;
			}
			if (other.isAlive() == false) {
				return;
			}
			if (unit.enforceNonPenetrationConstraint(other)) {
				System.out.println(unit + " <> " + unit);
				messenger.dispatch(Messages.COLLIDED_WITH, unit, other, 0, unit);
				messenger.dispatch(Messages.COLLIDED_WITH, other, unit, 0, unit);
			}
		}
	}

	private Color debugMap = new Color(1f, 1f, 0f, .7f);
	
	private void debug(Unit unit) {
		Drawing.setColor(Color.YELLOW);
		
		Vector2D sf = unit.getVelocity().copy();
		sf.mult(unit.getRadiusBounding() * 2);
		sf.add(unit.getPosition());
		Drawing.line(unit.getPosition(), sf);
				
		Drawing.setColor(Color.RED);
		Drawing.circle(unit.getPosition(), unit.getRadiusBounding());
		
		Drawing.setColor(Color.PINK);
		Drawing.circle(unit.getPosition(), unit.getViewDistance());
		
	}
	
	private void debug(Map map) {
		for (int y = map.getYDrawStart(); y < map.getYDrawEnd(); y++) {
			for (int x = map.getXDrawStart(); x < map.getXDrawEnd(); x++) {
				Tile t = map.getTile(x, y);
				Drawing.setColor(debugMap);
				Drawing.rect(t.getLeft(), t.getTop(), t.getWidth(), t.getHeight(), t.isUsed());
				Drawing.circle(t.getX(), t.getY(), 3, true);
			}
		}
	}
	
}
